home *** CD-ROM | disk | FTP | other *** search
/ Freelog 22 / freelog 22.iso / Prog / Djgpp / GPC2952B.ZIP / doc / gpc / demos / crtscreen.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-08  |  4.5 KB  |  130 lines

  1. /*
  2. This is not a GPC demo program, but a utility to make the
  3. CRTSavePreviousScreen feature of the CRT unit work on Linux consoles
  4. for normal users (for root and other users with access to the
  5. virtual console memory devices, it works without this utility). It's
  6. currently only for Linux, but may easily be ported to other systems
  7. that have something similar to Linux' virtual console memory
  8. devices, and no "alternate screen" features or similar (where those
  9. are present (e.g. in xterms, but not on the Linux console), this
  10. utility isn't needed, either).
  11.  
  12. Before installing it, please note that there is a little security
  13. issue: Direct access to the console's contents under Linux is done
  14. through the virtual console memory devices (/dev/vcsa*), rather than
  15. terminal operations, since kernel 1.1.92, so the system
  16. administrator can control access. This program is one way to grant
  17. limited access to them. It allows to save the screen contents and
  18. restore them later. As a security measure, to prevent terminal
  19. sniffing attacks, it refuses both saving and restoring while the
  20. invoking user has no read/write access to the corresponding
  21. terminal. This should be reasonably safe, but I can give no
  22. guarantee, so you might be careful about installing it on a
  23. multi-user system where security is a concern.
  24.  
  25. That said, if you want to install it, you have to give it read/write
  26. permissions to the virtual console memory devices. E.g., create a
  27. group (say, vcs), set the group ownership of these devices and the
  28. executable of this program to that group, make the devices group
  29. readable and writable, and give the exectuable the setgid privilege.
  30.  
  31. The following commands, executed as root, will do that:
  32.  
  33. gcc -Wall -O3 -s -o crtscreen crtscreen.c
  34. groupadd vcs
  35. chgrp vcs /dev/vcsa* crtscreen
  36. chmod g=rw /dev/vcsa*
  37. chmod 2555 crtscreen
  38.  
  39. It is NOT recommended to make this executable setuid root because
  40. that would increase the effects of any possible bugs.
  41.  
  42. Copyright (C) 1999-2001 Frank Heckenbach <frank@g-n-u.de>
  43.  
  44. This program is free software; you can redistribute it and/or
  45. modify it under the terms of the GNU General Public License as
  46. published by the Free Software Foundation, version 2.
  47.  
  48. This program is distributed in the hope that it will be useful,
  49. but WITHOUT ANY WARRANTY; without even the implied warranty of
  50. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  51. GNU General Public License for more details.
  52.  
  53. You should have received a copy of the GNU General Public License
  54. along with this program; see the file COPYING. If not, write to
  55. the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  56. Boston, MA 02111-1307, USA.
  57. */
  58.  
  59. #ifndef linux
  60. #error This program was only written for Linux.
  61. #endif
  62.  
  63. #include <unistd.h>
  64. #include <stdlib.h>
  65. #include <stdio.h>
  66. #include <string.h>
  67. #include <errno.h>
  68. #include <fcntl.h>
  69. #include <sys/types.h>
  70. #include <sys/stat.h>
  71.  
  72. #define DEV_TTY "/dev/tty"
  73. #define DEV_VCSA "/dev/vcsa"
  74.  
  75. static int VcsaFile, BufSize = 0x1000, Count = 0;
  76. static char *Buffer = 0, *tty;
  77.  
  78. static int crt_save_restore_screen_internal (int Restore)
  79. {
  80.   ssize_t r, c = 0;
  81.   /* Check if access to the terminal is currently permitted, using the
  82.      real user ID, in order to prevent terminal sniffing attacks. */
  83.   if (access (tty, R_OK | W_OK))
  84.     return 0;
  85.   lseek (VcsaFile, 0, SEEK_SET);
  86.   if (!Restore)
  87.     do
  88.       if ((!Buffer || c >= BufSize) && (!(Buffer = realloc (Buffer, BufSize *= 2))))
  89.         return 0;
  90.       else if ((r = read (VcsaFile, Buffer + c, BufSize - c)) >= 0)
  91.         Count = c += r;
  92.       else if (errno != EINTR)
  93.         return 0;
  94.     while (r);
  95.   else if (!Count)
  96.     return 0;
  97.   else
  98.     do
  99.       if ((r = write (VcsaFile, Buffer + c, Count - c)) >= 0)
  100.         c += r;
  101.       else if (errno != EINTR)
  102.         return 0;
  103.     while (r && c < Count);
  104.   return 1;
  105. }
  106.  
  107. int main ()
  108. {
  109.   char Mode, *t, Vcsa [100];
  110.   if (!getenv ("DISPLAY") && isatty (2) && (tty = ttyname (2))
  111.       && strlen (tty) <= sizeof (Vcsa) - strlen (DEV_VCSA) - 1
  112.       && !strncmp (tty, DEV_TTY, strlen (DEV_TTY))
  113.       && *(t = tty + strlen (DEV_TTY)) && !access (tty, R_OK | W_OK))
  114.     {
  115.       sprintf (Vcsa, DEV_VCSA "%s", t);
  116.       while (*t >= '0' && *t <= '9') t++;
  117.       if (!*t && (VcsaFile = open (Vcsa, O_RDWR)) >= 0)
  118.         while (read (0, &Mode, 1) > 0)
  119.           if (Mode == 'S' || Mode == 'R')
  120.             {
  121.               if (!crt_save_restore_screen_internal (Mode == 'R'))
  122.                 write (1, "E", 1);
  123.               else if (write (1, "O", 1) < 0 && errno != EINTR)
  124.                 break;
  125.             }
  126.     }
  127.   write (1, "F", 1);
  128.   return 1;
  129. }
  130.